/*
 * Matthew Cramer, Jesse Martinez, Marc Mendoza 
 * CSE 325 Lab 6
 * File: Tests.c
 * Description: Program to test the File System.  Reports tests that
 *              are being done and if they passed or *FAILED*.  
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../QueueManager/QueueManager.h"
#include "../FileSystem/FileSystem.h"

int main(int argc, char *argv[])
{
    int temp=0;
    char text1[500], text2[500];
    FILE *file1;
    FILE *file2;
    printf("\nTests for Lab 6 - File System\n");
    
/*********************************************
 Functionality Tests
 ********************************************/    
    printf("\n****Functionality Tests****\n");
    printf("These tests are conducted by comparing a sample\n");
    printf("output with the output of a file generated from\n");
    printf("running through the program.  These the output of\n");
    printf("the program checks the functionality of the functions\n");
    printf("and ensures that each output is correct.  If both\n");
    printf("of the files are the same, then the test PASSED.\n");
    printf("If both test files were not the same, then in FAILED.\n");
    printf("For a description of each test, see the documentation.\n");

	/*********************************************
     init_fs
     
     This test will check that the file system manager knows about the device and there
     is nothing else on the hard disk yet. It will also ensure that only one device can be
     initiated and that if init_fs is called again, it will clear the entire hard disk of data and
     reset it for the new device.
     ********************************************/
    printf("\n**init_fs**\n");
    temp=0;
    file1 = fopen("./Tests/Test_init_fs.txt","r");
    file2 = fopen("./Tests/Test_init_fs_OUTPUT.txt","r");
    if(file1 != NULL && file2 != NULL)
    {
        fgets(text1,500,file1);
        fgets(text2,500,file2);
        while((fgets(text1,500,file1) != NULL && fgets(text2,500,file2) != NULL) && temp != 1)
        {
            if(strcmp(text1, text2) != 0)
                temp = 1;
        }
        fclose(file1);
        fclose(file2);
    }
    else
        temp = 1;
    if(temp==0)
        printf("init_fs Arguments: PASSED\n");
    else
        printf("init_fs Arguments: *FAILED*\n");
    

    /*********************************************
     List
     
     This will ensure that when the list function is called, that it will list all devices, all
     file FCBs, and all valid files in the filesystem. If an argument is given it will check to
     see if it is the right type of argument, being devices, fileinfo [filename], or directory.
     If the argument is not a corresponding argument, it will report the error. If it is, it
     will display the device known to have valid file system, the FCB of a specified file, or
     list information about all valid files in the file system under valid directories. The list
     function will also ensure that if bad blocks have been located on the hard disk, it will
     show the new location of the block under the FCB for the file block that failed.
     ********************************************/
    printf("\n**List**\n");
    temp=0;
    file1 = fopen("./Tests/Test_List.txt","r");
    file2 = fopen("./Tests/Test_List_OUTPUT.txt","r");
    if(file1 != NULL && file2 != NULL)
    {
        fgets(text1,500,file1);
        fgets(text2,500,file2);
        while((fgets(text1,500,file1) != NULL && fgets(text2,500,file2) != NULL) && temp != 1)
        {
            if(strcmp(text1, text2) != 0)
                temp = 1;
        }
        fclose(file1);
        fclose(file2);
    }
    else
        temp = 1;
    if(temp==0)
        printf("List: PASSED\n");
    else
        printf("List: *FAILED*\n");

	/*********************************************
    format
     
     This test will ensure that the device is formatted properly to the specified size and
     the name specified is associated with the device. It will also ensure that only one file
     system is formated for the one device.
    ********************************************/
    printf("\n**format**\n");
    temp=0;
    file1 = fopen("./Tests/Test_format.txt","r");
    file2 = fopen("./Tests/Test_format_OUTPUT.txt","r");
    if(file1 != NULL && file2 != NULL)
    {
        fgets(text1,500,file1);
        fgets(text2,500,file2);
        while((fgets(text1,500,file1) != NULL && fgets(text2,500,file2) != NULL) && temp != 1)
        {
            if(strcmp(text1, text2) != 0)
                temp = 1;
        }
        fclose(file1);
        fclose(file2);
    }
    else
        temp = 1;
    if(temp==0)
        printf("format: PASSED\n");
    else
        printf("format: *FAILED*\n");
    
    /*********************************************
     mount
     
     This test will ensure that the internal system structures is allocated properly for the
     file system and that the correct FCB is changed. This test will also ensure that none of
     the file commands can be used since the file system is not mounted.
     ********************************************/
    printf("\n**mount**\n");
    temp=0;
    file1 = fopen("./Tests/Test_mount.txt","r");
    file2 = fopen("./Tests/Test_mount_OUTPUT.txt","r");
    if(file1 != NULL && file2 != NULL)
    {
        fgets(text1,500,file1);
        fgets(text2,500,file2);
        while((fgets(text1,500,file1) != NULL && fgets(text2,500,file2) != NULL) && temp != 1)
        {
            if(strcmp(text1, text2) != 0)
                temp = 1;
        }
        fclose(file1);
        fclose(file2);
    }
    else
        temp = 1;
    if(temp==0)
        printf("mount: PASSED\n");
    else
        printf("mount: *FAILED*\n");
    
	/*********************************************
    open
     
     This test will ensure that the argument supplied with the open function performs
     the proper corresponding action and that the specified file is the file that is opened and
     located in the specified directory. It will also ensure all the correct arguments are given
     and used correctly.
    ********************************************/
    printf("\n**open**\n");
    temp=0;
    file1 = fopen("./Tests/Test_open.txt","r");
    file2 = fopen("./Tests/Test_open_OUTPUT.txt","r");
    if(file1 != NULL && file2 != NULL)
    {
        fgets(text1,500,file1);
        fgets(text2,500,file2);
        while((fgets(text1,500,file1) != NULL && fgets(text2,500,file2) != NULL) && temp != 1)
        {
            if(strcmp(text1, text2) != 0)
                temp = 1;
        }
        fclose(file1);
        fclose(file2);
    }
    else
        temp = 1;
    if(temp==0)
        printf("open: PASSED\n");
    else
        printf("open: *FAILED*\n");

    /*********************************************
     read
     
     This test will check that the correct file is being read from in the specified directory,
     the proper block is read, and the block is placed in the buffer properly in the hardware
     simulated portion of the device controller.
     ********************************************/
    printf("\n**read**\n");
    temp=0;
    file1 = fopen("./Tests/Test_read.txt","r");
    file2 = fopen("./Tests/Test_read_OUTPUT.txt","r");
    if(file1 != NULL && file2 != NULL)
    {
        fgets(text1,500,file1);
        fgets(text2,500,file2);
        while((fgets(text1,500,file1) != NULL && fgets(text2,500,file2) != NULL) && temp != 1)
        {
            if(strcmp(text1, text2) != 0)
                temp = 1;
        }
        fclose(file1);
        fclose(file2);
    }
    else
        temp = 1;
    if(temp==0)
        printf("read: PASSED\n");
    else
        printf("read: *FAILED*\n");

	/*********************************************
     write
     
     This test will check that the correct file is being written to in the specified directory,
     the proper block is written, and the block is placed in the buffer properly in the
     hardware simulated portion of the device controller.
    ********************************************/
    printf("\n**write**\n");
    temp=0;
    file1 = fopen("./Tests/Test_write.txt","r");
    file2 = fopen("./Tests/Test_write_OUTPUT.txt","r");
    if(file1 != NULL && file2 != NULL)
    {
        fgets(text1,500,file1);
        fgets(text2,500,file2);
        while((fgets(text1,500,file1) != NULL && fgets(text2,500,file2) != NULL) && temp != 1)
        {
            if(strcmp(text1, text2) != 0)
                temp = 1;
        }
        fclose(file1);
        fclose(file2);
    }
    else
        temp = 1;
    if(temp==0)
        printf("write: PASSED\n");
    else
        printf("write: *FAILED*\n");

    /*********************************************
     close
     
     This test will check the FCB of the file being closed is properly updated and that
     the file exists.
     ********************************************/
    printf("\n**close**\n");
    temp=0;
    file1 = fopen("./Tests/Test_close.txt","r");
    file2 = fopen("./Tests/Test_close_OUTPUT.txt","r");
    if(file1 != NULL && file2 != NULL)
    {
        fgets(text1,500,file1);
        fgets(text2,500,file2);
        while((fgets(text1,500,file1) != NULL && fgets(text2,500,file2) != NULL) && temp != 1)
        {
            if(strcmp(text1, text2) != 0)
                temp = 1;
        }
        fclose(file1);
        fclose(file2);
    }
    else
        temp = 1;
    if(temp==0)
        printf("close: PASSED\n");
    else
        printf("close: *FAILED*\n");
    
    /*********************************************
     delete
     
     This test will check that the correct directory and/or files are deleted and the memory
     is properly returned to the free pool of blocks on the hard disk. This will be done
     by checking pointers of header blocks that they were properly reset.
     ********************************************/
    printf("\n**delete**\n");
    temp=0;
    file1 = fopen("./Tests/Test_delete.txt","r");
    file2 = fopen("./Tests/Test_delete_OUTPUT.txt","r");
    if(file1 != NULL && file2 != NULL)
    {
        fgets(text1,500,file1);
        fgets(text2,500,file2);
        while((fgets(text1,500,file1) != NULL && fgets(text2,500,file2) != NULL) && temp != 1)
        {
            if(strcmp(text1, text2) != 0)
                temp = 1;
        }
        fclose(file1);
        fclose(file2);
    }
    else
        temp = 1;
    if(temp==0)
        printf("delete: PASSED\n");
    else
        printf("delete: *FAILED*\n");
    
    /*********************************************
     unmount
     
     This text will check to see if a file system is mounted then unmount it by setting
     the mount bit in the file system header to unmount. This will be confirmed by trying
     to do functions with the file system which will not be allowed since the file system is
     not mounted. This test will also make sure the arguments are checked correctly for this
     function and return the proper errors if not.
     ********************************************/
    printf("\n**unmount**\n");
    temp=0;
    file1 = fopen("./Tests/Test_unmount.txt","r");
    file2 = fopen("./Tests/Test_unmount_OUTPUT.txt","r");
    if(file1 != NULL && file2 != NULL)
    {
        fgets(text1,500,file1);
        fgets(text2,500,file2);
        while((fgets(text1,500,file1) != NULL && fgets(text2,500,file2) != NULL) && temp != 1)
        {
            if(strcmp(text1, text2) != 0)
                temp = 1;
        }
        fclose(file1);
        fclose(file2);
    }
    else
        temp = 1;
    if(temp==0)
        printf("unmount: PASSED\n");
    else
        printf("unmount: *FAILED*\n");
    
    /*********************************************
     Bad Blocks
     
     Bad blocks will be tested by making bad blocks in memory and making sure that
     the back up memory will be referenced by the bad blocks correctly using pointers. This
     will be done by calling the function and using the list function to ensure the address
     of the block has now changed to the new block. It will also check to ensure that if a
     allocated valid block is set to a bad block, that the whole directory or file be deleted.
     ********************************************/
    printf("\n**bad_block**\n");
    temp=0;
    file1 = fopen("./Tests/Test_bad_block.txt","r");
    file2 = fopen("./Tests/Test_bad_block_OUTPUT.txt","r");
    if(file1 != NULL && file2 != NULL)
    {
        fgets(text1,500,file1);
        fgets(text2,500,file2);
        while((fgets(text1,500,file1) != NULL && fgets(text2,500,file2) != NULL) && temp != 1)
        {
            if(strcmp(text1, text2) != 0)
                temp = 1;
        }
        fclose(file1);
        fclose(file2);
    }
    else
        temp = 1;
    if(temp==0)
        printf("bad_block: PASSED\n");
    else
        printf("bad_block: *FAILED*\n");
    
    /*********************************************
     create_directory
     
     This test will ensure that once a file system has been mounted, that a directory be
     created first before any files can be created, since each file has to be in a directory. This
     test will ensure that the file system knows about all the directories and assign the right
     files to each directory. his test will also make sure the arguments are checked correctly
     for this function and return the proper errors if not.
     ********************************************/
    printf("\n**create_directory**\n");
    temp=0;
    file1 = fopen("./Tests/Test_create_directory.txt","r");
    file2 = fopen("./Tests/Test_create_directory_OUTPUT.txt","r");
    if(file1 != NULL && file2 != NULL)
    {
        fgets(text1,500,file1);
        fgets(text2,500,file2);
        while((fgets(text1,500,file1) != NULL && fgets(text2,500,file2) != NULL) && temp != 1)
        {
            if(strcmp(text1, text2) != 0)
                temp = 1;
        }
        fclose(file1);
        fclose(file2);
    }
    else
        temp = 1;
    if(temp==0)
        printf("create_directory: PASSED\n");
    else
        printf("create_directory: *FAILED*\n");
 
    
/*********************************************
 Capacitiy Tests
********************************************/    
    
    printf("\n****Capacitiy Tests****\n");
   
    /*********************************************
     Empty Hard Disk
     
     This test will ensure that when the file system is formatted, there is no data in the
     file system and will call the different list functions to ensure all the error statements are
     displayed correctly.
     ********************************************/  
    printf("**Empty Hard Drive**\n");
    
	if(getSizeOfHD() == 0)
		printf("Empty Hard Disk: PASSED\n");
	else
		printf("Empty Hard Disk: *FAILED*\n");
    
    initHD();
    if(getSizeOfHD() == 268)
		printf("Empty Hard Disk with Initialize: PASSED\n");
	else
		printf("Empty Hard Disk with Initialize: *FAILED*\n");
    

    /*********************************************
     Max Hard Drive
     
     This will ensure that the maximum number of files can be created. The test will
     create files until the max number of files is made and then all files are listed with the
     list command to check that all files are created properly under directories.
     ********************************************/    
    printf("\n**Max Hard Drive**\n");
    temp=0;
    format();
    mountfs();
    int i;
    for(i=0; i<100; i++)
    {
        create_directory(i);
    }

    if(getSizeOfHD()==368)
    {
        printf("Directory Max: PASSED\n");
        temp++;
    }
    else
        printf("Directory Max: *FAILED*\n");
    
    for(i=0; i<60; i++)
    {
        openFile(0,i,0);
        openFile(0,i,2);
    }

    if(getSizeOfHD()==428)
    {
        printf("File Max: PASSED\n");
        temp++;
    }
    else
        printf("File Max: *FAILED*\n");
    
    int j;
    for(i=0; i<60; i++)
    {
        for(j=0; j<1024; j++)
        {
            writeBlock(0,i,j,0);
        }
    }

    if(getSizeOfHD()==61868)
    {
        printf("Max File Writes: PASSED\n");
        temp++;
    }
    else
        printf("Max File Writes: *FAILED*\n");
   
    if(temp == 3)
        printf("Overall Max Hard Drive: PASSED\n");
    else
        printf("Overall Max Hard Drive: *FAILED*\n");
    
      return 0;
}
